package com.ftg.learn.Config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 *  对路由的添加、删除、修改等操作
 * @author Guo
 * @date 2022/3/28
 */
@Slf4j
@Component
public class GatewayRouteImp implements ApplicationEventPublisherAware {


    @Autowired
    RouteDefinitionRepository repository;

    @Autowired
    ApplicationEventPublisher aep;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.aep = applicationEventPublisher;
    }


    /**
     * 删除路由
     * @param id dataid
     * @return String
     */
    public String delete(String id) {
        try {
            log.info("gateway delete route id {}",id);
            this.repository.delete(Mono.just(id)).subscribe();
            this.aep.publishEvent(new RefreshRoutesEvent(this));
            return "delete success";
        } catch (Exception e) {
            return "delete fail";
        }
    }

    /**
     * 更新路由
     * @param definitions  列表
     * @return String
     */
    public String updateList(List<RouteDefinition> definitions) {
        log.info("gateway update route {}",definitions);
        List<RouteDefinition> routeDefinitionsExits =  repository.getRouteDefinitions().buffer().blockFirst();
        if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
            routeDefinitionsExits.forEach(routeDefinition -> {
                log.info("delete routeDefinition:{}", routeDefinition);
                delete(routeDefinition.getId());
            });
        }
        definitions.forEach(definition -> updateById(definition));
        return "success";
    }

    /**
     * 更新路由
     * @param definition  列表
     * @return String
     */
    public String updateById(RouteDefinition definition) {
        try {
            log.info("gateway update route {}",definition);
            this.repository.delete(Mono.just(definition.getId()));
        } catch (Exception e) {
            return "update fail,not find route  routeId: "+definition.getId();
        }
        try {
            repository.save(Mono.just(definition)).subscribe();
            this.aep.publishEvent(new RefreshRoutesEvent(this));
            return "success";
        } catch (Exception e) {
            return "update route fail";
        }
    }

    /**
     * 增加路由
     * @param definition  单个路由
     * @return String
     */
    public String add(RouteDefinition definition) {
        log.info("gateway add route {}",definition);
        repository.save(Mono.just(definition)).subscribe();
        this.aep.publishEvent(new RefreshRoutesEvent(this));
        return "success";
    }


}
